// 蜂窝蜜造平台生成代码，此文件只生成一次，不需要添加到 .beeignore

package com.fowo.api.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fowo.api.common.excel.TemplateModelBuildEventListener;
import com.fowo.api.common.model.DataIndex;
import com.fowo.api.common.model.ImportRow;
import com.fowo.api.common.model.PageSearchFilter;
import com.fowo.api.common.model.RException;
import com.fowo.api.common.util.SheetUtils;
import com.fowo.api.controller.shipment.entity.ShipPlansSubImportPo;
import com.fowo.api.controller.shipment.entity.shipmentImportPo;
import com.fowo.api.entity.ListingFather;
import com.fowo.api.entity.Product;
import com.fowo.api.entity.ShopInfo;
import com.fowo.api.mapper.ShopInfoMapper;
import com.fowo.api.model.logistics.provider.LogisticsProviderItemVo;
import com.fowo.api.model.ship.plans.ShipPlansItemVo;
import com.fowo.api.model.ship.plans.ShipPlansVo;

import com.fowo.api.model.ship.plans.sub.ShipPlansSubItemVo;
import com.fowo.api.model.ship.plans.sub.ShipPlansSubSearchParamPo;
import com.fowo.api.model.ship.plans.sub.ShipPlansSubVo;
import com.fowo.api.model.shop.info.ShopInfoItemVo;
import com.fowo.api.model.shop.info.ShopInfoSearchParamPo;
import com.fowo.api.model.warehouse.bin.WarehouseBinItemVo;
import com.fowo.api.model.warehouse.bin.WarehouseBinSearchParamPo;
import com.fowo.api.service.ListingFatherService;
import com.fowo.api.sys.entity.SysDict;
import com.fowo.api.sys.entity.SysFile;
import com.fowo.api.sys.entity.SysImportTemplate;
import com.fowo.api.sys.model.SysDictAllItem;
import com.fowo.api.sys.service.FileService;
import com.fowo.api.sys.service.SysDictService;
import com.fowo.api.sys.service.impl.SysDictServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.validation.ConstraintViolation;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 发货计划单 服务实现类
 */
@Service
public class ShipPlansServiceImpl extends ShipPlansBaseServiceImpl {
    @Resource
    protected FileService fileService;
    @Resource
    protected ShopInfoServiceImpl shopInfoService;
    @Resource
    protected ProductServiceImpl productService;
    @Resource
    private SysDictServiceImpl sysDictService;
    @Resource
    private ListingFatherServiceImpl listingFatherService;


    @Transactional(rollbackFor = Exception.class)
    @Override
    public Long create(ShipPlansVo model) throws Exception {
        model.setStatus("1");
        //计算发货计划之和
        if (model.getProductList()!= null && model.getProductList().size() > 0) {
            Optional<Long> reduce = model.getProductList().stream().map(ShipPlansSubItemVo::getPlannedShipment).reduce(Long::sum);
            model.setPlannedShipment(reduce.get()!=null?reduce.get().longValue():null);
            model.getProductList().forEach(item -> {
                item.setState("0");
                item.setGenerateshipment("0");
                //设置listing名称
                if (item.getDeliveryWarehouseStoreFnsku()!= null) {
                    ListingFather listingFather = listingFatherService.getById(item.getDeliveryWarehouseStoreFnsku());
                    item.setFnskuname(listingFather.getFnsku());
                }
            });
        }
        Long aLong = super.create(model);
        return  aLong;
    }
    @Override
    protected Page<?> appendWithChild(Page<ShipPlansItemVo> pageResult) {
        Page<JSONObject> withChildPage = new Page<>(
                pageResult.getCurrent(),
                pageResult.getSize(),
                pageResult.getTotal()
        );
        withChildPage.setRecords(new ArrayList<>());
        for (ShipPlansItemVo itemVo : pageResult.getRecords()) {
            JSONObject itemJson = (JSONObject) JSONObject.toJSON(itemVo);
            withChildPage.getRecords().add(itemJson);

            ShipPlansSubSearchParamPo productListSearchParamPo =
                    new ShipPlansSubSearchParamPo();
            productListSearchParamPo.setPageSize(200);
            productListSearchParamPo.setParentShipPlans(itemVo.getId());
            itemJson.put(
                    "productList",
                    shipPlansSubService.pageSearch(productListSearchParamPo)
            );
        }
        return withChildPage;
    }

    public List<ImportRow<ShipPlansSubImportPo>> importPreview2(
            MultipartFile file
    ) throws Exception {

        List<ImportRow<ShipPlansSubImportPo>> rows = new ArrayList<>();

        // 读取 Excel 到 rows
        EasyExcel
                .read(file.getInputStream())
                .useDefaultListener(false)
                .registerReadListener(
                        new TemplateModelBuildEventListener<>(
                                ShipPlansSubImportPo.class,
                                null
                        ) {
                            @Override
                            public void invokeRow(
                                    ShipPlansSubImportPo row,
                                    AnalysisContext cxt
                            ) {
                                ShipPlansSubVo vo = new ShipPlansSubVo();
                                ImportRow<ShipPlansSubImportPo> ir = excelToImportRow(
                                        row,
                                        cxt.readRowHolder().getRowIndex(),
                                        vo,
                                        null,
                                        false
                                );
                                if (ir.isEmptyRow()) {
                                    return;
                                }
                                if (false) {
                                    // FIXME: 未在平台上配置此对象《作为导入唯一识别》的《逻辑分组》配置，无法处理更新模式
                                }
                                rows.add(ir);
                            }
                        }
                )
                .sheet()
                .doRead();

        return rows;
    }

    protected ImportRow<ShipPlansSubImportPo> excelToImportRow(
            ShipPlansSubImportPo row,
            Integer rowNumber,
            ShipPlansSubVo vo,
            Map<String, Object> variables,
            boolean allowOverrides
    ) {
        ImportRow<ShipPlansSubImportPo> ir = new ImportRow<ShipPlansSubImportPo>();
        ir.setRowNumber(rowNumber);
        ir.setRow(row);
        if (SheetUtils.isAllFieldsEmpty(row)) {
            ir.setEmptyRow(true);
            ir.addError("", "空行");
            return ir;
        }
        final Set<ConstraintViolation<ShipPlansSubImportPo>> validate =
                validator.validate(row);
        boolean isOutputVo = vo != null;
        if (!isOutputVo) {
            vo = new ShipPlansSubVo();
        }
        //SCM00076

        //收集基本校验错误
        ir.initErrors(validate, ShipPlansSubImportPo.class);
        BeanUtils.copyProperties(row, vo);
        List<SysDictAllItem> scm00018 = sysDictService.getDictItems("SCM00076");

        List<SysDictAllItem> collect = scm00018.stream().filter(x -> x.getItemText().equals(row.getPackagingType())).collect(Collectors.toList());
        if(collect.size()==0){
            ir.addError("shopIdShopName", row.getPackagingType()+"未能在字典中找到匹配的数据");
        }
        row.setPackagingType(collect.size()>0?collect.get(0).getItemValue():null);
        ShopInfo byId = shopInfoService.getOne(Wrappers.<ShopInfo>query().lambda().eq(ShopInfo::getShopName,row.getShopIdShopName()));
        if(byId==null){
            ir.addError("shopIdShopName", row.getShopIdShopName()+"未能在店铺中找到匹配的数据");
        }
        row.setShopId(byId!=null?byId.getId():null);
        Product one = productService.getOne(Wrappers.<Product>query().lambda().eq(Product::getSku, row.getSku()));
        if(one==null){
            ir.addError("SKU", row.getSku()+"未能在产品中找到匹配的数据");
        }
        List<ListingFather> list =new ArrayList<>();
        if(byId!=null){
            list=listingFatherService.list(Wrappers.<ListingFather>query().lambda()
                    .eq(ListingFather::getShop,byId.getId())
                    .eq(ListingFather::getMsku, row.getMsku()));
        }
        if(list.size()==0){
            ir.addError("MSKU", row.getMsku()+"未能在Listing中找到匹配的数据");
        }else{
            ListingFather listingFather = list.get(0);
            if(listingFather.getPairProduct()==null){
                ir.addError("MSKU", row.getMsku()+"在Listing中没有匹配SKU");
            }
        }
        if(one!=null){
            row.setProductId(one.getId());
            row.setImgUrl(one.getPicUrl());
            row.setProductName(one.getName());
        }
        if(list.size()>0){
            ListingFather listingFather = list.get(0);
            row.setFnskuId(listingFather.getId());
            row.setFnsku(listingFather.getFnsku());
            row.setAsin(listingFather.getAsin());
            row.setTitle(listingFather.getTitle());
            row.setParentAsin(listingFather.getParentAsin());
        }
        return ir;
    }

    public Object importPreview3(MultipartFile file,Long shopId) throws IOException {
        List<ImportRow<shipmentImportPo>> rows = new ArrayList<>();

        // 读取 Excel 到 rows
        EasyExcel
                .read(file.getInputStream())
                .useDefaultListener(false)
                .registerReadListener(
                        new TemplateModelBuildEventListener<>(
                                shipmentImportPo.class,
                                null
                        ) {
                            @Override
                            public void invokeRow(
                                    shipmentImportPo row,
                                    AnalysisContext cxt
                            ) {
//                                ShipPlansSubVo vo = new ShipPlansSubVo();
                                ImportRow<shipmentImportPo> ir = excelToImportRow2(
                                        row,
                                        cxt.readRowHolder().getRowIndex(),
                                        null,
                                        null,
                                        false,
                                        shopId
                                );
                                if (ir.isEmptyRow()) {
                                    return;
                                }
                                if (false) {
                                    // FIXME: 未在平台上配置此对象《作为导入唯一识别》的《逻辑分组》配置，无法处理更新模式
                                }
                                rows.add(ir);
                            }
                        }
                )
                .sheet()
                .doRead();

        return rows;
    }

    protected ImportRow<shipmentImportPo> excelToImportRow2(
            shipmentImportPo row,
            Integer rowNumber,
            ShipPlansSubVo vo,
            Map<String, Object> variables,
            boolean allowOverrides,
            Long shopId
    ) {
        ImportRow<shipmentImportPo> ir = new ImportRow<shipmentImportPo>();
        ir.setRowNumber(rowNumber);
        ir.setRow(row);
        if (SheetUtils.isAllFieldsEmpty(row)) {
            ir.setEmptyRow(true);
            ir.addError("", "空行");
            return ir;
        }
        final Set<ConstraintViolation<shipmentImportPo>> validate =
                validator.validate(row);
        boolean isOutputVo = vo != null;
//        if (!isOutputVo) {
//            vo = new ShipPlansSubVo();
//        }
        //SCM00076
        shipmentImportPo shipmentImportPo=new shipmentImportPo();
        //收集基本校验错误
        ir.initErrors(validate, shipmentImportPo.class);
        BeanUtils.copyProperties(row, shipmentImportPo);

        List<ListingFather> list = listingFatherService.list(Wrappers.<ListingFather>query().lambda()
                        .eq(ListingFather::getShop,shopId)
                .eq(ListingFather::getMsku, row.getMsku()));
        if(list.size()==0){
            ir.addError("MSKU",  row.getMsku()+"未能在listing中找到匹配的数据");
        }else {
            ListingFather listingFather = list.get(0);
            if(listingFather.getPairProduct()==null){
                ir.addError("MSKU",  row.getMsku()+"在listing未匹配SKU");
            }
            row.setFnskuId(listingFather.getId());
            row.setFnsku(listingFather.getFnsku());
            row.setPicUrl(listingFather.getImg());
            row.setAsin(listingFather.getAsin());
            row.setTitle(listingFather.getTitle());
            row.setProductId(listingFather.getPairProduct());
            Product byId = productService.getById(listingFather.getPairProduct());
            row.setSku(byId!=null?byId.getSku():null);
            row.setProductName(byId!=null?byId.getName():null);
            row.setParentAsin(listingFather.getParentAsin());
        }

//        ShopInfo byId = shopInfoService.getOne(Wrappers.<ShopInfo>query().lambda().eq(ShopInfo::getShopName,row.getShopIdShopName()));
//        if(byId==null){
//            ir.addError("shopIdShopName", row.getShopIdShopName()+"未能在店铺中找到匹配的数据");
//        }
//        row.setShopId(byId!=null?byId.getId():null);
//        Product one = productService.getOne(Wrappers.<Product>query().lambda().eq(Product::getSku, row.getSku()));
//        if(one==null){
//            ir.addError("shopIdShopName", row.getSku()+"未能在产品中找到匹配的数据");
//        }
//        row.setProductId(one!=null?one.getId():null);
////        row.setImgUrl(one!=null?one.getPicUrl():null);
//        row.setProductName(one!=null?one.getName():null);

        return ir;
    }
}
